package ren.nearby.http.di;

import android.content.Context;

import com.facebook.stetho.okhttp3.StethoInterceptor;
import com.orhanobut.logger.Logger;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

import javax.inject.Singleton;

import dagger.Module;
import dagger.Provides;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.logging.HttpLoggingInterceptor;
import okio.Buffer;
import ren.nearby.http.progress.ProgressResponseBody2;
import ren.nearby.http.utils.util.AppUtils;
import ren.nearby.http.utils.util.PreferencesUtils;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * Created by Administrator on 2017/9/1 0001.
 */
@Module
public class HttpModule3 {

    private static final String F_BREAK = " %n";
    private static final String F_URL = " %s";
    private static final String F_TIME = " in %.1fms";
    private static final String F_HEADERS = "%s";
    private static final String F_RESPONSE = F_BREAK + "Response: %d";
    private static final String F_BODY = "body: %s";

    private static final String F_BREAKER = F_BREAK + "-------------------------------------------" + F_BREAK;
    private static final String F_REQUEST_WITHOUT_BODY = F_URL + F_TIME + F_BREAK + F_HEADERS;
    private static final String F_RESPONSE_WITHOUT_BODY = F_RESPONSE + F_BREAK + F_HEADERS + F_BREAKER;
    private static final String F_REQUEST_WITH_BODY = F_URL + F_TIME + F_BREAK + F_HEADERS + F_BODY + F_BREAK;
    private static final String F_RESPONSE_WITH_BODY = F_RESPONSE + F_BREAK + F_HEADERS + F_BODY + F_BREAK + F_BREAKER;

    private final Context mContext;
    private final int mKey;//证书key

    public HttpModule3(Context context, int key) {
//        Logger.e(context == null ? "上下文为空" : "上下文不为空");
//        Logger.e(key == 0 ? "证书文件为空" : "证书文件不为空");
        mContext = context;
        mKey = key;
    }

    @Provides
    @Singleton
    Context provideContext() {
        return mContext;
    }

    /**
     * 1.构建retrofit
     */
    @Provides
    @Singleton
    protected HttpApi provideHttpApi(Retrofit retrofit) {
        return retrofit.create(HttpApi.class);
    }

    public String stringifyResponseBody(String responseBody) {
        return responseBody;
    }

    private static String stringifyRequestBody(Request request) {
        try {
            final Request copy = request.newBuilder().build();
            final Buffer buffer = new Buffer();
            copy.body().writeTo(buffer);
            return buffer.readUtf8();
        } catch (final IOException e) {
            return "did not work";
        }
    }


    @Provides
    @Singleton
    protected Retrofit provideRetrofit() {
        OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
        //拦截请求调试 我们打开Chrome，在地址栏输入chrome://inspect/
        builder.addNetworkInterceptor(new StethoInterceptor());
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        //拦截请求输出内容
        builder.addInterceptor(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request request = chain.request();

                Request.Builder requestBuilder = request.newBuilder();
                //添加请求头
                Request signedRequest = requestBuilder
                        .addHeader("NBlock", "1")
                        .addHeader("sessionToken", "")
                        .addHeader("q_version", AppUtils.getVerCode(mContext) + "")
                        .addHeader("device_id", "android-1001")
                        .addHeader("device_os", "android")
                        .addHeader("device_osversion", AppUtils.getSDKVersion() + "")
                        .addHeader("app_name", "Nearby")
                        .addHeader("sign", "")
                        .addHeader("uuid", PreferencesUtils.getString(mContext, "uuid", "0"))
                        .build();
                long t1 = System.nanoTime();
                Response response = chain.proceed(signedRequest);
                //别问为什么 因为日志打印的数据 body会丢失 所有这里处理判断url进行额外处理下载
                if (signedRequest.url().toString().contains(".apk")) {
                    Logger.e("进入下载 ...");
                    return response
                            .newBuilder()
                            .body(new ProgressResponseBody2(response))
                            .build();
                }


                long t2 = System.nanoTime();
                MediaType contentType = null;
                String bodyString = null;
                if (response.body() != null) {
                    contentType = response.body().contentType();
                    bodyString = response.body().string();
                }
                double time = (t2 - t1) / 1e6d;

                switch (request.method()) {
                    case "GET":
                        Logger.e(String.format(
                                "GET" + F_REQUEST_WITHOUT_BODY + F_RESPONSE_WITH_BODY,
                                signedRequest.url(),
                                time,
                                signedRequest.headers(),
                                response.code(),
                                response.headers(),
                                stringifyResponseBody(bodyString)));
                        break;
                    case "POST":
                        Logger.e(String.format(
                                "POST" + F_REQUEST_WITH_BODY + F_RESPONSE_WITH_BODY,
                                signedRequest.url(),
                                time,
                                signedRequest.headers(),
                                stringifyRequestBody(signedRequest),
                                response.code(),
                                response.headers(),
                                stringifyResponseBody(bodyString)));
                        break;
                    case "PUT":
                        Logger.e(String.format(
                                "POST" + F_REQUEST_WITH_BODY + F_RESPONSE_WITH_BODY,
                                signedRequest.url(),
                                time,
                                signedRequest.headers(),
                                signedRequest.body().toString(),
                                response.code(),
                                response.headers(),
                                stringifyResponseBody(bodyString)));
                        break;
                    case "DELETE":
                        Logger.e(
                                String.format("DELETE " + F_REQUEST_WITHOUT_BODY + F_RESPONSE_WITHOUT_BODY,
                                        signedRequest.url(),
                                        time,
                                        signedRequest.headers(),
                                        response.code(),
                                        response.headers()));
                        break;
                }
                if (response.body() != null) {
                    // 深坑！
                    // 打印body后原ResponseBody会被清空，需要重新设置body
                    ResponseBody body = ResponseBody.create(contentType, bodyString);
                    return response.newBuilder().body(body).build();
                } else {
                    return response;
                }

            }
        });
        //设置出现错误重链
        builder.retryOnConnectionFailure(true);
        //设置超时时间
        builder.connectTimeout(15, TimeUnit.SECONDS);
        OkHttpClient okHttpClient = builder.build();
        return new Retrofit.Builder()
                .client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .baseUrl(HttpApi.BASE_URL)
                .build();
    }

}
